package com.xhwl.data.controller;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.xhwl.common.dto.cent.sdata.*;
import com.xhwl.common.enums.AppTypeEnum;
import com.xhwl.common.enums.config.IndustryEnum;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.enums.sdata.EnterpriseTypeEnum;
import com.xhwl.common.pojo.AbstractAccount;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.devplatform.Developer;
import com.xhwl.common.query.cent.sdata.AccountQuery;
import com.xhwl.common.query.cent.sdata.EnterpriseQuery;
import com.xhwl.common.query.cent.sdata.OrganizationQuery;
import com.xhwl.common.query.cent.sdata.ProjectQuery;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.common.vo.cent.sdata.EnterpriseRentVO;
import com.xhwl.common.vo.cent.sdata.EnterpriseSpaceDetailDTO;
import com.xhwl.common.vo.cent.sdata.ProjectPermissionVO;
import com.xhwl.data.dao.ISceneAppDao;
import com.xhwl.data.dao.ISceneDao;
import com.xhwl.data.dao.ISceneEnterpriseDao;
import com.xhwl.data.pojo.vo.NameCheckedVO;
import com.xhwl.data.service.*;
import com.xhwl.data.util.AutoCodeUtils;
import com.xhwl.data.util.CodePrefixConstant;
import com.xhwl.data.util.ValidatorUtil;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.xml.transform.Result;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 企业
 *
 * @Author: luyi
 * @Description:
 * @Date: Create in 9:08 2021/1/14
 */
@RestController
public class EnterpriseController {

    @Autowired
    private IEnterpriseService enterpriseService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private ISceneDao sceneDao;

    @Autowired
    private ISceneAppDao sceneAppDao;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IAccountService accountService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IAccountRoleService accountRoleService;

    @Autowired
    private IEnterpriseSpaceService enterpriseSpaceService;

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IEnterprisePermissionService enterprisePermissionService;

    @Autowired
    private IEnterpriseProjectService enterpriseProjectService;

    private static final String KEY = "ENTERPRISE:CODE";
    //注册的游客角色
    private String REGISTER_TOURIST_ROLE_CODE = "TOURIST1";

    private static final Logger log = LoggerFactory.getLogger(EnterpriseController.class);

    @Autowired
    private IEnterpriseExtraService enterpriseExtraService;

    @Autowired
    private ISceneEnterpriseDao sceneEnterpriseDao;

    /**
     * 详情
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param id
     * @return
     */
    @RequestMapping(value = "/ent/detail", method = RequestMethod.GET)
    public ResultJson detail(@RequestHeader(value = "appId", required = true) String appId,
                             @RequestHeader(value = "clientType", required = false) Integer clientType,
                             @RequestHeader(value = "industryId", required = true) Short industryId, Integer id, Account account) {
        if (null == id) {
            return ResultJson.fail("参数错误");
        }
        Enterprise ent = enterpriseService.getOne(id, account);
        if (null == ent) {
            return ResultJson.fail("企业不存在");
        }
        return ResultJson.success(detail(ent));
    }

    /**
     * 详情
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param id
     * @return
     */
    @RequestMapping(value = "/ent/detail-admin", method = RequestMethod.GET)
    public ResultJson adminDetail(@RequestHeader(value = "appId", required = true) String appId,
                                  @RequestHeader(value = "clientType", required = false) Integer clientType,
                                  @RequestHeader(value = "industryId", required = true) Short industryId, Integer id) {
        if (null == id) {
            return ResultJson.fail("参数错误");
        }
        Enterprise ent = enterpriseService.findById(id);
        if (null == ent) {
            return ResultJson.fail("企业不存在");
        }
        return ResultJson.success(detail(ent));
    }

    /**
     * 详情
     *
     * @param ent
     * @return
     */
    private EnterpriseDTO detail(Enterprise ent) {
        EnterpriseDTO enterpriseDTO = new EnterpriseDTO();
        BeanUtils.copyProperties(ent, enterpriseDTO);
        //查询企业扩展属性
        JSONObject extra = enterpriseExtraService.list(ent.getId());
        enterpriseDTO.setExtra(extra);
        enterpriseDTO.setRegion(getRegion(ent.getProvinceId(), ent.getCityId(), ent.getDistrictId()));
        // 回显企业管理员
        enterpriseMangerSetter(ent.getId(), enterpriseDTO);
        enterprisePermissionSetter(ent.getId(), enterpriseDTO);
        // 企业类型
        if (!StringUtils.isEmpty(ent.getType())) {
            String[] split = ent.getType().split(",");
            enterpriseDTO.setTypes(Arrays.stream(split).map(i -> Integer.valueOf(i)).collect(Collectors.toList()));
        }
        // 回显租赁空间
        if (ent.getType().contains(EnterpriseTypeEnum.ENTER.id.toString())) {
            rentSpaceSetter(ent, enterpriseDTO);
        }
        projectInfoSetter(ent.getId(), enterpriseDTO);
        //场景id
        QueryWrapper<SceneEnterprise> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enterprise_id",ent.getId());
        List<SceneEnterprise> sceneEnterprises = sceneEnterpriseDao.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(sceneEnterprises)){
            List<Integer> collect = sceneEnterprises.stream().map(i -> i.getSceneId()).distinct().collect(Collectors.toList());
            enterpriseDTO.setSceneIds(collect);
            QueryWrapper<Scene> sceneQueryWrapper = new QueryWrapper<>();
            sceneQueryWrapper.in("id",collect);
            List<Scene> scenes = sceneDao.selectList(sceneQueryWrapper);
            if(!CollectionUtils.isEmpty(scenes)){
                List<String> names = scenes.stream().map(i -> i.getName()).distinct().collect(Collectors.toList());
                enterpriseDTO.setSceneNames(Joiner.on(",").join(names));
            }
        }
        enterprisePermissionSceneSetter(enterpriseDTO);
        return enterpriseDTO;
    }

    /**
     * 组装场景结构
     * @param enterpriseDTO
     */
    private void enterprisePermissionSceneSetter(EnterpriseDTO enterpriseDTO){
        if(CollectionUtils.isEmpty(enterpriseDTO.getSceneIds()) || CollectionUtils.isEmpty(enterpriseDTO.getPermissionTree())){
            return;
        }
        List<AppPermissionMenuDTO> permissionTree = enterpriseDTO.getPermissionTree();
        //key:appCode
        Map<String,AppPermissionMenuDTO> map = new HashMap<>();
        for(AppPermissionMenuDTO vo:permissionTree){
            map.put(vo.getApp().getCode(),vo);
        }
        List<ScenePermissionMenuDTO> result = new ArrayList<>();
        ScenePermissionMenuDTO scenePermissionMenuDTO = null;
        List<AppPermissionMenuDTO> appPermissionMenuDTOS = null;
        for(Integer sceneId:enterpriseDTO.getSceneIds()){
            scenePermissionMenuDTO = new ScenePermissionMenuDTO();
            //获得场景
            Scene scene = sceneDao.selectById(sceneId);
            scenePermissionMenuDTO.setScene(scene);
            //获得关联app
            QueryWrapper<SceneApp> sceneAppQueryWrapper = new QueryWrapper<>();
            sceneAppQueryWrapper.eq("scene_code",scene.getCode());
            List<SceneApp> sceneApps = sceneAppDao.selectList(sceneAppQueryWrapper);
            appPermissionMenuDTOS = new ArrayList<>();
            if(CollectionUtils.isEmpty(sceneApps)){
                return;
            }
            for(SceneApp vo:sceneApps){
                if(map.get(vo.getAppCode()) != null) {
                    appPermissionMenuDTOS.add(map.get(vo.getAppCode()));
                }
            }
            //获得权限
            scenePermissionMenuDTO.setAppPermissionMenuDTOS(appPermissionMenuDTOS);
            result.add(scenePermissionMenuDTO);
        }
        enterpriseDTO.setScenePermissionMenuDTOS(result);
    }

    /**
     * 回显企业权限
     *
     * @param id
     * @param enterpriseDTO
     */
    public void enterprisePermissionSetter(Integer id, EnterpriseDTO enterpriseDTO) {
        List<Permission> permissionList = permissionService.getListByEnterpriseId(null, id);
        if (null != permissionList && !permissionList.isEmpty()) {
            //List<Integer> permissionIds = permissionList.stream().filter(p -> p.getMenuType() != 0).map(Permission::getId).collect(Collectors.toList());
            List<Integer> permissionIds = permissionList.stream().map(Permission::getId).collect(Collectors.toList());
            log.info("permission size {}", permissionIds.size());
            enterpriseDTO.setPermissions(permissionIds);
            // 回显企业权限树
            PermissionTreeDTO permissionTreeDTO = new PermissionTreeDTO();
            permissionTreeDTO.setIds(permissionIds);
            enterpriseDTO.setPermissionTree(permissionService.getPermissionTree(permissionTreeDTO));
        }
    }

    /**
     * 填充项目相关
     *
     * @param id
     * @param enterpriseDTO
     */
    public void projectInfoSetter(Integer id, EnterpriseDTO enterpriseDTO) {
        // 回显项目权限
        projectPermissionSetter(id, enterpriseDTO);
        // 回显授权项目
        authProjectSetter(id, enterpriseDTO);
    }

    /**
     * 项目授权填充
     *
     * @param id
     * @param enterpriseDTO
     */
    public void projectPermissionSetter(Integer id, EnterpriseDTO enterpriseDTO) {
        QueryWrapper<EnterprisePermission> enterprisePermissionQueryWrapper = new QueryWrapper<>();
        enterprisePermissionQueryWrapper.eq("enterprise_id", id);
        enterprisePermissionQueryWrapper.isNotNull("project_id");
        List<EnterprisePermission> list2 = enterprisePermissionService.list(enterprisePermissionQueryWrapper);
        if (!list2.isEmpty()) {
            Map<Integer, List<Integer>> collect = list2.stream().collect(Collectors.groupingBy(EnterprisePermission::getProjectId, Collectors.mapping(EnterprisePermission::getPermissionId, Collectors.toList())));
            List<ProjectPermissionVO> projectPermissionVOS = new ArrayList<>(collect.size());
            for (Map.Entry<Integer, List<Integer>> entry : collect.entrySet()) {
                ProjectPermissionVO projectPermissionVO = new ProjectPermissionVO();
                projectPermissionVO.setProjectId(entry.getKey());
                projectPermissionVO.setPermissionIds(entry.getValue());
                projectPermissionVOS.add(projectPermissionVO);
            }
            enterpriseDTO.setProjectPermissionVOS(projectPermissionVOS);
        }
    }

    /**
     * 项目授权填充
     *
     * @param id
     * @param enterpriseDTO
     */
    public void authProjectSetter(Integer id, EnterpriseDTO enterpriseDTO) {
        QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
        enterpriseProjectQueryWrapper.eq("enterprise_id", id);
        List<EnterpriseProject> list3 = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
        if (!list3.isEmpty()) {
            List<Integer> collect = list3.stream().map(i -> i.getProjectId()).collect(Collectors.toList());
            QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
            projectQueryWrapper.select("name");
            projectQueryWrapper.in("id", collect);
            List<Project> list4 = projectService.list(projectQueryWrapper);
            enterpriseDTO.setAuthProjectIds(collect);
            enterpriseDTO.setAuthProjectNames(list4.stream().map(i -> i.getName()).collect(Collectors.toList()));
        }
    }

    /**
     * 填充企业管理员
     *
     * @param id
     * @param enterpriseDTO
     */
    public void enterpriseMangerSetter(Integer id, EnterpriseDTO enterpriseDTO) {
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.select("id");
        roleQueryWrapper.eq("is_initialized", true);
        roleQueryWrapper.eq("enterprise_id", id);
        roleQueryWrapper.eq("is_deleted", false);
        roleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.code);
        List<Role> list = roleService.list(roleQueryWrapper);
        if (!list.isEmpty()) {
            QueryWrapper<AccountRole> accountRoleQueryWrapper = new QueryWrapper<>();
            accountRoleQueryWrapper.in("role_id", list.stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<AccountRole> list1 = accountRoleService.list(accountRoleQueryWrapper);
            if (!list1.isEmpty()) {
                QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
                accountQueryWrapper.select("id", "name", "login_name", "phone");
                accountQueryWrapper.eq("is_deleted", false);
                accountQueryWrapper.in("id", list1.stream().map(i -> i.getAccountId()).collect(Collectors.toList()));
                List<Account> list2 = accountService.list(accountQueryWrapper);
                if (!CollectionUtils.isEmpty(list2)) {
                    enterpriseDTO.setManagers(list2);
                    Account account = list2.get(0);
                    AccountDTO accountDTO = new AccountDTO();
                    BeanUtils.copyProperties(account, accountDTO);
                    enterpriseDTO.setAdminAccount(accountDTO);
                } else {
                    log.warn("企业管理员帐号不存在");
                }

            } else {
                log.info("没有企业管理员帐号");
            }
        } else {
            log.warn("当前企业 {} 没有企业管理员角色", id);
        }
    }

    /**
     * 填充租赁空间
     *
     * @param ent
     * @param enterpriseDTO
     */
    private void rentSpaceSetter(Enterprise ent, EnterpriseDTO enterpriseDTO) {
        QueryWrapper<EnterpriseSpace> enterpriseSpaceQueryWrapper = new QueryWrapper<>();
        enterpriseSpaceQueryWrapper.eq("enterprise_id", ent.getId());
        List<EnterpriseSpace> list1 = enterpriseSpaceService.list(enterpriseSpaceQueryWrapper);
        if (!CollectionUtils.isEmpty(list1)) {
            List<Integer> collect = list1.stream().map(i -> i.getOrganizationId()).distinct().collect(Collectors.toList());
            List<Organization> organizations = organizationService.listByIds(collect);
            if (!CollectionUtils.isEmpty(organizations)) {
                Map<Integer, List<Organization>> collect1 = organizations.stream().collect(Collectors.groupingBy(Organization::getProjectId, Collectors.toList()));
                List<Integer> collect4 = organizations.stream().map(i -> i.getProjectId()).distinct().collect(Collectors.toList());
                List<Project> projects = projectService.listByIds(collect4);
                Map<Integer, String> collect5 = projects.stream().collect(Collectors.toMap(Project::getId, Project::getName));
                List<EnterpriseRentVO> list2 = new ArrayList<>(collect1.size());
                for (Map.Entry<Integer, List<Organization>> integerListEntry : collect1.entrySet()) {
                    EnterpriseRentVO enterpriseRentVO = new EnterpriseRentVO();
                    enterpriseRentVO.setProjectId(integerListEntry.getKey());
                    enterpriseRentVO.setProjectName(collect5.get(integerListEntry.getKey()));
                    List<Integer> collect2 = integerListEntry.getValue().stream().map(i -> i.getId()).collect(Collectors.toList());
                    List<String> collect3 = integerListEntry.getValue().stream().map(i -> i.getName()).collect(Collectors.toList());
                    enterpriseRentVO.setSpaceIds(collect2);
                    enterpriseRentVO.setSpaceName(collect3);
                    List<EnterpriseSpace> spaces = list1.stream().filter(i -> collect2.contains(i.getOrganizationId())).collect(Collectors.toList());
                    if (null != spaces.get(0) && null != spaces.get(0).getRentEndTime() && null != spaces.get(0).getRentStartTime()){
                        enterpriseRentVO.setRentEndTime(spaces.get(0).getRentEndTime());
                        enterpriseRentVO.setRentStartTime(spaces.get(0).getRentStartTime());
                    }
                    list2.add(enterpriseRentVO);
                }
                enterpriseDTO.setEnterpriseRentVOS(list2);
            }
        }
    }

    /**
     * 新增/修改
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param enterpriseDTO
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/create", method = RequestMethod.POST)
    public ResultJson create(@RequestHeader(value = "appId", required = true) String appId,
                             @RequestHeader(value = "clientType", required = false) Integer clientType,
                             @RequestHeader(value = "industryId", required = true) Short industryId,
                             @RequestBody EnterpriseDTO enterpriseDTO, Account account) {
        ResultJson checkResult = check(enterpriseDTO);
        if (!checkResult.getState()) {
            return checkResult;
        }
        if (null == enterpriseDTO.getIndustryId()) {
            enterpriseDTO.setIndustryId(industryId);
        }
        // 运营商权限信息只能在运管平台修改
        if (!CollectionUtils.isEmpty(enterpriseDTO.getTypes()) && enterpriseDTO.getTypes().contains(EnterpriseTypeEnum.OPERATOR.id.intValue())) {
            enterpriseDTO.setUpdatePermission(false);
        } else {
            enterpriseDTO.setUpdateCurrentIndustry(industryId.intValue());
        }
        if (null != enterpriseDTO.getId()) {
            if (null == enterpriseDTO.getParentId() && enterpriseDTO.getParentId().equals(enterpriseDTO.getId())) {
                return ResultJson.fail("运营商错误");
            }
            enterpriseDTO.setDevelopId(account.getDevelopId());
            return enterpriseService.update(enterpriseDTO, enterpriseDTO.getPermissions(), account);
        }
        return enterpriseService.create(enterpriseDTO, enterpriseDTO.getPermissions(), account);
    }

    /**
     * 新增/修改
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param enterpriseDTO
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/create-admin", method = RequestMethod.POST)
    public ResultJson createAdmin(@RequestHeader(value = "appId", required = true) String appId,
                                  @RequestHeader(value = "clientType", required = false) Integer clientType,
                                  @RequestHeader(value = "industryId", required = false) Short industryId,
                                  @RequestBody EnterpriseDTO enterpriseDTO, Account account, Developer develop) {

        ResultJson check = check(enterpriseDTO);
        if (!check.getState()) {
            return check;
        }
        if (CollectionUtils.isEmpty(enterpriseDTO.getTypes())) {
            enterpriseDTO.setTypes(Arrays.asList(EnterpriseTypeEnum.OPERATOR.id.intValue()));
        }
        enterpriseDTO.setIndustryId(industryId);
        if (null != enterpriseDTO.getId()) {
            enterpriseDTO.setDevelopId(develop.getId());
            return enterpriseService.update(enterpriseDTO, enterpriseDTO.getPermissions(), account);
        }
        return enterpriseService.create(enterpriseDTO, enterpriseDTO.getPermissions(), account);
    }

    /**
     * 编码
     *
     * @return
     */
    @RequestMapping(value = "/ent/auto-code")
    public ResultJson getCode() {
//        Long increment = redisTemplate.opsForValue().increment(KEY);
//        String code = AutoCodeUtils.codeFormat(CodePrefixConstant.ENT_PREFIX, increment.intValue(), CodePrefixConstant.CODE_LENGTH);
        String code = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 8);
        return ResultJson.success(code);
    }

    /**
     * 检查名称
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param checked
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/name-check", method = RequestMethod.POST)
    public ResultJson nameCheck(@RequestHeader(value = "appId", required = true) String appId,
                                @RequestHeader(value = "clientType", required = false) Integer clientType,
                                @RequestHeader(value = "industryId", required = true) Short industryId,
                                @RequestBody NameCheckedVO checked, Account account) {
        EnterpriseQuery enterpriseQuery = new EnterpriseQuery();
        enterpriseQuery.setName(checked.getName());
        enterpriseQuery.setIndustryIdList(Arrays.asList(industryId));
        if (null != checked.getId()) {
            enterpriseQuery.setExcludeId(checked.getId());
        }
        Enterprise enterprise = enterpriseService.find(enterpriseQuery, account);
        if (null == enterprise) {
            return ResultJson.success("检查通过");
        } else {
            return ResultJson.fail("已存在");
        }
    }

    /**
     * 列表
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param enterpriseQuery
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/list", method = RequestMethod.POST)
    public ResultJson list(@RequestHeader(value = "appId", required = true) String appId,
                           @RequestHeader(value = "clientType", required = false) Integer clientType,
                           @RequestHeader(value = "industryId", required = true) Short industryId,
                           @RequestBody EnterpriseQuery enterpriseQuery, Account account) {
        List<Enterprise> list = enterpriseService.list(enterpriseQuery, account);
        return ResultJson.success(list);
    }

    /**
     * 分页
     *
     * @param enterpriseQuery
     * @param page
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/page")
    public ResultJson page(@RequestBody EnterpriseQuery enterpriseQuery, Page page, Account account) {
        page.setOrders(OrderItem.descs("updated_at"));
        if (null == enterpriseQuery.getShowChild()) {
            enterpriseQuery.setShowChild(true);
        }
        if (null != account) {
            List<Role> roles = roleService.getRoleListByAccountId(account.getId());
            if (!roles.isEmpty()) {
                if (StringUtils.isNotEmpty(roles.get(0).getCode())) {
                    if (roles.get(0).getCode().equals(REGISTER_TOURIST_ROLE_CODE)) {
                        return ResultJson.success(enterpriseService.page(enterpriseQuery, page, null));
                    }
                }
            }
        }
        Page<Enterprise> page1 = enterpriseService.page(enterpriseQuery, page, account);
        return ResultJson.success(convertView(page1));
    }

    /**
     * 获取入住商或服务商列表
     *
     * @param enterpriseId
     * @param types
     * @return
     */
    @RequestMapping(value = "/ent/list-by-id", method = RequestMethod.GET)
    public ResultJson listById(@RequestParam(value = "enterpriseId", required = true) Integer enterpriseId,
                               @RequestParam(value = "types", required = true) List<Integer> types) {
        return ResultJson.success(enterpriseService.listById(enterpriseId, types));
    }

    /**
     * 查询入住企业对应员工数
     *
     * @param enterpriseId
     * @return
     */
    @RequestMapping(value = "/ent/count-residentEnterprise", method = RequestMethod.GET)
    public ResultJson countResidentEnterprise(Integer enterpriseId){
        if (null == enterpriseId){
            return ResultJson.fail("参数错误");
        }
        return ResultJson.success(enterpriseService.countResidentEntStaffs(enterpriseId));
    }

    @RequestMapping(value = "/ent/tree", method = RequestMethod.GET)
    public ResultJson tree(@RequestParam(value = "enterpriseId", required = true) Integer enterpriseId,
                           @RequestParam(value = "types", required = true) List<Integer> types) {
        return enterpriseService.tree(enterpriseId, types);
    }

    /**
     * logo
     *
     * @param enterpriseDTO
     * @return
     */
    @RequestMapping(value = "/ent/logo")
    public ResultJson logo(@RequestBody EnterpriseDTO enterpriseDTO) {
        if (null == enterpriseDTO.getId()) {
            return ResultJson.fail("id不能为空");
        }
        return enterpriseService.updateLogo(enterpriseDTO.getId(), enterpriseDTO.getLogo());
    }

    /**
     * 删除
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param id
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/delete", method = RequestMethod.POST)
    public ResultJson delete(@RequestHeader(value = "appId", required = true) String appId,
                             @RequestHeader(value = "clientType", required = false) Integer clientType,
                             @RequestHeader(value = "industryId", required = true) Short industryId,
                             Integer id, Account account) {
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withEnterpriseId(id);
        List<Project> list = projectService.list(projectQuery, account);
        if (!list.isEmpty()) {
            log.error("企业 {} 下存在校园，无法删除", id);
            return ResultJson.fail("删除失败");
        }
        return enterpriseService.delete(id, account);
    }

    /**
     * 删除
     *
     * @param appId
     * @param clientType
     * @param industryId
     * @param id
     * @param account
     * @return
     */
    @RequestMapping(value = "/ent/admin/delete", method = RequestMethod.POST)
    public ResultJson adminDelete(@RequestHeader(value = "appId", required = true) String appId,
                                  @RequestHeader(value = "clientType", required = false) Integer clientType,
                                  @RequestHeader(value = "industryId", required = true) Short industryId,
                                  Integer id, Account account) {
        ProjectQuery projectQuery = new ProjectQuery();
        projectQuery.withEnterpriseId(id);
        List<Project> list = projectService.list(projectQuery, account);
        if (!list.isEmpty()) {
            log.error("企业 {} 下存在校园，无法删除", id);
            return ResultJson.fail("删除失败");
        }
        return enterpriseService.deleteAdmin(id, account);
    }

    /**
     * 禁用
     *
     * @param id
     * @param isBan
     * @return
     */
    @RequestMapping(value = "/ent/ban")
    public ResultJson ban(
            Account account, Integer id, Boolean isBan, App app, AdminAccount adminAccount) {
        if (null == id || null == isBan) {
            return ResultJson.fail("参数错误");
        }
        AbstractAccount abstractAccount = account == null ? adminAccount : account;
        Enterprise enterprise = enterpriseService.findById(id);
        if (null == enterprise) {
            return ResultJson.fail("企业不存在");
        }
        if (enterprise.getType().contains(EnterpriseTypeEnum.OPERATOR.id.toString()) && AppTypeEnum.SYSTEM.type != app.getAppType()) {
            return ResultJson.fail("无法操作");
        }
        return enterpriseService.setBan(abstractAccount, id, isBan);
    }

    /**
     * 企业选择器
     *
     * @return
     */
    @PostMapping("/ent/chose")
    public ResultJson enterpriseChose(@RequestBody EnterpriseQuery enterpriseQuery, Account account) {

        if (null == account || null == account.getId()) {
            return ResultJson.fail("缺少帐号信息");
        }
        List<Enterprise> enterprises = enterpriseService.list(enterpriseQuery, account);
        Integer defaultEnterprise = accountService.getById(account.getId()).getDefaultEnterprise();
        for (Enterprise enterprise : enterprises) {
            if (null != defaultEnterprise && enterprise.getId().equals(defaultEnterprise)){
                enterprise.setSelectedEnterprise(true);
                break;
            }
        }
        return ResultJson.success(enterprises);
    }


    /**
     * 运管平台分页查询
     *
     * @param enterpriseQuery
     * @return
     */
    @PostMapping(value = "/ent/admin/page")
    public ResultJson page(@RequestBody EnterpriseQuery enterpriseQuery) {
        enterpriseQuery.getPage().setOrders(OrderItem.descs("updated_at"));
        Page<Enterprise> page1 = enterpriseService.page(enterpriseQuery, enterpriseQuery.getPage(), null);
        return ResultJson.success(convertView(page1));
    }


    private ResultJson check(EnterpriseDTO enterpriseDTO) {
        if (null == enterpriseDTO) {
            return ResultJson.fail("参数错误");
        }
//        if (null != enterpriseDTO.getId()) {
//            if (null != enterpriseDTO.getAdminAccount()) {
//                AccountDTO adminAccount = enterpriseDTO.getAdminAccount();
//                if (null == adminAccount.getId()) {
//                    log.warn("缺少企业管理员信息");
//                    return ResultJson.fail("缺少企业管理员信息");
//                }
//            }
//        }
        //企管信息选填
        if (null == enterpriseDTO.getId()) {
            if (null != enterpriseDTO.getAdminAccount()) {
                AccountDTO adminAccount = enterpriseDTO.getAdminAccount();
                if (null == adminAccount.getName() || null == adminAccount.getPassword() || null == adminAccount.getPhone()) {
                    return ResultJson.fail("参数错误");
                }
                if (!ValidatorUtil.isMobile(adminAccount.getPhone())) {
                    return ResultJson.fail("请输入正确的手机号");
                }
            }
        }
        if (StringUtils.isEmpty(enterpriseDTO.getName())) {
            return ResultJson.fail("企业名称必须填写");
        }
        if (2 > enterpriseDTO.getName().trim().length() || 24 < enterpriseDTO.getName().trim().length()) {
            return ResultJson.fail("请输入2-24个字符");
        }
        if (StringUtils.isNotEmpty(enterpriseDTO.getAddress()) && 50 < enterpriseDTO.getAddress().length()) {
            return ResultJson.fail("详细地址超长");
        }
        if (!CollectionUtils.isEmpty(enterpriseDTO.getTypes()) && !enterpriseDTO.getTypes().contains(EnterpriseTypeEnum.OPERATOR.id.intValue())) {
            if (null == enterpriseDTO.getParentId() || 0 == enterpriseDTO.getParentId()) {
                return ResultJson.fail("缺少运营商信息");
            }
        }
        /*if (CollectionUtils.isEmpty(enterpriseDTO.getSceneIds())) {
            return ResultJson.fail("请选择场景");
        }*/
        return ResultJson.success("检查通过");
    }

    public String getRegion(Integer provincesId, Integer cityId, Integer districtId) {
        List<Integer> integers = Arrays.asList(provincesId, cityId, districtId);
        List<Region> regions = regionService.findByIds(integers);
        if (regions.isEmpty()) {
            return null;
        }
        Map<Integer, String> reMap = regions.stream().collect(Collectors.toMap(Region::getId, Region::getName));
        StringBuilder sbd = new StringBuilder();
        if (null != provincesId && StringUtils.isNotEmpty(reMap.get(provincesId))) {
            sbd.append(reMap.get(provincesId));
        }
        if (null != cityId && StringUtils.isNotEmpty(reMap.get(cityId))) {
            sbd.append(reMap.get(cityId));
        }
        if (null != districtId && StringUtils.isNotEmpty(reMap.get(districtId))) {
            sbd.append(reMap.get(districtId));
        }
        return sbd.toString();
    }

    private Page<EnterpriseDTO> convertView(Page enterprisePage) {
        List<Enterprise> records = enterprisePage.getRecords();
        if (null == records || records.isEmpty()) {
            return new Page<>();
        }
        List<EnterpriseDTO> enterpriseDTOS = new ArrayList<>(records.size());
        // 入驻的企业
        List<Integer> thirdEnterprise = new ArrayList<>();
        // 所在地区
        List<Integer> regionSet = new ArrayList<>();
        Map<Integer, String> regionNameMap = new HashMap<>();
        if (!records.isEmpty()) {
            records.stream().forEach(p -> {
                if (null != p.getProvinceId()) {
                    regionSet.add(p.getProvinceId());
                }
                if (null != p.getCityId()) {
                    regionSet.add(p.getCityId());
                }
                if (null != p.getDistrictId()) {
                    regionSet.add(p.getDistrictId());
                }
                if (!EnterpriseTypeEnum.OPERATOR.id.toString().equals(p.getType())) {
                    thirdEnterprise.add(p.getId());
                }
            });
            List<Region> regions = regionService.findByIds(regionSet);
            regionNameMap = regions.stream().collect(Collectors.toMap(Region::getId, Region::getName));
        }
        // 查询企业管理员
        List<Integer> collect = records.stream().map(i -> i.getId()).collect(Collectors.toList());
        Map<Integer, AccountDTO> manager = getManager(collect);
        // 租赁空间填充
        Map<Integer, List<EnterpriseRentVO>> rentSpaceMap = rentSpaceCovert(collect);
        // 查询入住项目
        Map<Integer, List<Project>> enterpriseProjectMap = new HashMap<>();
        if (!thirdEnterprise.isEmpty()) {
            QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
            enterpriseProjectQueryWrapper.in("enterprise_id", thirdEnterprise);
            List<EnterpriseProject> enterpriseProjects = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
            if (!enterpriseProjects.isEmpty()) {
                List<Integer> collect1 = enterpriseProjects.stream().map(i -> i.getProjectId()).collect(Collectors.toList());
                QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                projectQueryWrapper.select("id", "name");
                projectQueryWrapper.in("id", collect1);
                projectQueryWrapper.eq("is_deleted", false);
                List<Project> list = projectService.list(projectQueryWrapper);
                Map<Integer, Project> projectMap = list.stream().collect(Collectors.toMap(Project::getId, Function.identity()));
                Map<Integer, List<Integer>> collect2 = enterpriseProjects.stream().collect(Collectors.groupingBy(EnterpriseProject::getEnterpriseId, Collectors.mapping(EnterpriseProject::getProjectId, Collectors.toList())));
                for (Map.Entry<Integer, List<Integer>> entry : collect2.entrySet()) {
                    List<Integer> value = entry.getValue();
                    if (!CollectionUtils.isEmpty(value)) {
                        List<Project> projects = new ArrayList<>();
                        for (Integer integer : value) {
                            Project project = projectMap.get(integer);
                            if (null != project) {
                                projects.add(project);
                            }
                        }
                        enterpriseProjectMap.put(entry.getKey(), projects);
                    }
                }
            }
        }
        for (Enterprise enterprise : records) {
            EnterpriseDTO enterpriseDTO = new EnterpriseDTO();
            BeanUtils.copyProperties(enterprise, enterpriseDTO);
            StringBuilder sbd = new StringBuilder();
            if (null != enterprise.getProvinceId()) {
                sbd.append(regionNameMap.get(enterprise.getProvinceId()));
            }
            if (null != enterprise.getCityId()) {
                sbd.append(regionNameMap.get(enterprise.getCityId()));
            }
            if (null != enterprise.getDistrictId()) {
                sbd.append(regionNameMap.get(enterprise.getDistrictId()));
            }
            if (StringUtils.isNotEmpty(sbd.toString())) {
                enterpriseDTO.setRegion(sbd.toString());
            }
            enterpriseDTO.setAdminAccount(manager.get(enterprise.getId()));
            // 企业类型
            if (!StringUtils.isEmpty(enterprise.getType())) {
                String[] split = enterprise.getType().split(",");
                enterpriseDTO.setTypes(Arrays.stream(split).map(i -> Integer.valueOf(i)).collect(Collectors.toList()));
            }
            List<Project> projects = enterpriseProjectMap.get(enterprise.getId());
            if (!CollectionUtils.isEmpty(projects)) {
                enterpriseDTO.setAuthProjectIds(projects.stream().map(i -> i.getId()).collect(Collectors.toList()));
                enterpriseDTO.setAuthProjectNames(projects.stream().map(i -> i.getName()).collect(Collectors.toList()));
            }
            if (!CollectionUtils.isEmpty(rentSpaceMap.get(enterprise.getId())) && enterprise.getType().contains(EnterpriseTypeEnum.ENTER.id.toString())) {
                enterpriseDTO.setEnterpriseRentVOS(rentSpaceMap.get(enterprise.getId()));
            }
            //设置场景
            List<String> names = sceneEnterpriseDao.findEntNames(enterprise.getId());
            if(!CollectionUtils.isEmpty(names)){
                enterpriseDTO.setSceneNames(Joiner.on(",").join(names));
            }
            enterpriseDTOS.add(enterpriseDTO);
        }
        return enterprisePage.setRecords(enterpriseDTOS);
    }

    private Map<Integer, AccountDTO> getManager(List<Integer> enterpriseIds) {
        if (CollectionUtils.isEmpty(enterpriseIds)) {
            return Collections.emptyMap();
        }
        // 查询企业管理员角色
        QueryWrapper<Role> roleQueryWrapper = new QueryWrapper<>();
        roleQueryWrapper.in("enterprise_id", enterpriseIds);
        roleQueryWrapper.eq("type", RoleTypeEnum.MANAGER.code);
        roleQueryWrapper.eq("is_initialized", true);
        roleQueryWrapper.eq("is_deleted", false);
        List<Role> list = roleService.list(roleQueryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            log.warn("企业缺少企业管理员角色");
            return Collections.emptyMap();
        }
        Map<Integer, Integer> roleEnterpriseMap = list.stream().collect(Collectors.toMap(Role::getId, Role::getEnterpriseId));
        // 查询企业管理员帐号
        Map<Integer, List<Account>> roleAccountMap = accountService.getByRoleIds(list.stream().map(i -> i.getId()).collect(Collectors.toList()));
        Map<Integer, AccountDTO> accountDTOMap = new HashMap<>(roleAccountMap.size());
        for (Map.Entry<Integer, List<Account>> integerListEntry : roleAccountMap.entrySet()) {
            List<Account> value = integerListEntry.getValue();
            if (CollectionUtils.isEmpty(value)) {
                continue;
            }
            Account account = value.get(0);
            if (null == account) {
                continue;
            }
            AccountDTO accountDTO = new AccountDTO();
            accountDTO.setName(account.getName());
            accountDTO.setPhone(account.getPhone());
            accountDTOMap.put(roleEnterpriseMap.get(integerListEntry.getKey()), accountDTO);
        }
        return accountDTOMap;
    }

    private Map<Integer, List<EnterpriseRentVO>> rentSpaceCovert(List<Integer> entIds) {
        Map<Integer, List<EnterpriseRentVO>> map = new HashMap<>();
        if (CollectionUtils.isEmpty(entIds)) {
            return map;
        }
        QueryWrapper<EnterpriseSpace> enterpriseSpaceQueryWrapper = new QueryWrapper<>();
        enterpriseSpaceQueryWrapper.in("enterprise_id", entIds);
        List<EnterpriseSpace> list = enterpriseSpaceService.list(enterpriseSpaceQueryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            Map<Integer, List<EnterpriseSpace>> entSpaceMap = list.stream().collect(Collectors.groupingBy(EnterpriseSpace::getEnterpriseId));
            for (Integer entId : entIds) {
                if (!CollectionUtils.isEmpty(entSpaceMap.get(entId))) {
                    List<EnterpriseSpace> enterpriseSpaces = entSpaceMap.get(entId);
                    List<Integer> orgIds = entSpaceMap.get(entId).stream().map(i -> i.getOrganizationId()).distinct().collect(Collectors.toList());
                    List<Organization> organizations = organizationService.listByIds(orgIds);
                    if (!CollectionUtils.isEmpty(organizations)) {
                        Map<Integer, List<Organization>> orgMap = organizations.stream().collect(Collectors.groupingBy(Organization::getProjectId, Collectors.toList()));
                        List<Integer> projectIds = organizations.stream().map(i -> i.getProjectId()).distinct().collect(Collectors.toList());
                        List<Project> projects = projectService.listByIds(projectIds);
                        Map<Integer, String> projectMap = projects.stream().collect(Collectors.toMap(Project::getId, Project::getName));
                        List<EnterpriseRentVO> enterpriseRentVOList = new ArrayList<>(orgMap.size());
                        for (Map.Entry<Integer, List<Organization>> integerListEntry : orgMap.entrySet()) {
                            EnterpriseRentVO enterpriseRentVO = new EnterpriseRentVO();
                            enterpriseRentVO.setProjectId(integerListEntry.getKey());
                            enterpriseRentVO.setProjectName(projectMap.get(integerListEntry.getKey()));
                            List<Integer> spaceIds = integerListEntry.getValue().stream().map(i -> i.getId()).collect(Collectors.toList());
                            List<String> spaceNames = integerListEntry.getValue().stream().map(i -> i.getName()).collect(Collectors.toList());
                            enterpriseRentVO.setSpaceIds(spaceIds);
                            enterpriseRentVO.setSpaceName(spaceNames);
                            List<EnterpriseSpace> spaces = enterpriseSpaces.stream().filter(i->spaceIds.contains(i.getOrganizationId())).collect(Collectors.toList());
                            EnterpriseSpace enterpriseSpace = spaces.get(0);
                            if (null != enterpriseSpace.getRentStartTime() && null != enterpriseSpace.getRentEndTime()){
                                enterpriseRentVO.setRentStartTime(enterpriseSpace.getRentStartTime());
                                enterpriseRentVO.setRentEndTime(enterpriseSpace.getRentEndTime());
                            }
                            enterpriseRentVOList.add(enterpriseRentVO);
                        }
                        map.put(entId, enterpriseRentVOList);
                    }
                }
            }
        }
        return map;
    }
    /**
     * 入驻企业租赁空间路址查询
     *
     * @param query 参数
     * @return
     */
    @PostMapping("/ent/space/org")
    public ResultJson getEnterpriseSpace(@RequestBody EnterpriseQuery query, List<Integer> types) {
        ResultJson<List<EnterpriseSpace>> enterpriseSpace = enterpriseSpaceService.getEnterpriseSpace(query);
        Map<Integer, String> resultMap = new HashMap<>();
        if (enterpriseSpace.getState()) {
            List<EnterpriseSpace> result = enterpriseSpace.getResult();
            if (CollectionUtils.isEmpty(result)) {
                for (EnterpriseSpace space : result) {
                    OrganizationQuery organizationQuery = new OrganizationQuery();
                    organizationQuery.setId(space.getOrganizationId());
                    organizationQuery.setLevel(types);
                    String fullName = organizationService.fullName(organizationQuery);
                    resultMap.put(space.getEnterpriseId(), fullName);
                }
            }
        }
        return ResultJson.successWithResult(resultMap);
    }

    /**
     * 企业管理--统计楼层下所有【经营品类】的企业
     *
     * @param floorOrgId
     * @return
     */
    @PostMapping(value = "/ent/find-catgory-ent-by-floorOrgId")
    public ResultJson findCatoryEntByFloorOrgId(Integer floorOrgId){
        return ResultJson.success(enterpriseService.countCatrgoryByFloorOrg(floorOrgId));
    }

    /**
     * 获取企业&租赁空间名称（指定单个orgId）
     *
     * @param enterpriseSpaceDetailDTO
     * @return
     */
    @PostMapping("/ent/space/detail-list")
    public ResultJson getEnterpriseSpaceDetail(@RequestBody EnterpriseSpaceDetailDTO enterpriseSpaceDetailDTO) {
        return ResultJson.success(enterpriseSpaceService.getEnterpriseSpaceDetail(enterpriseSpaceDetailDTO));
    }

    @PostMapping("/ent/getAll")
    public ResultJson getAll() {
        return ResultJson.success(enterpriseService.getAll());
    }

}


